﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Meraz.Core.Model;
using Meraz.Core.Commands;
using Ninject;
using Meraz.Core.Helpers;
using Meraz.Core.Repositories;

namespace Meraz.Core.Managers
{
    public class PostManager
    {
        [Inject]
        public ICreateAliasesCommand CreateAliasesCommand { get; set; }
        [Inject]
        public ICreateDomainsCommand CreateDomainsCommand { get; set; }
        [Inject]
        public ICreatePostCommand CreatePostCommand { get; set; }
        [Inject]
        public ICreateUrlsCommand CreateUrlsCommand { get; set; }
        [Inject]
        public IGetBlogCommand GetBlogCommand { get; set; }
        [Inject]
        public IGetLinkCommand GetLinkCommand { get; set; }
        [Inject]
        public IGetPostCommand GetPostCommand { get; set; }
        [Inject]
        public IGetPosterCommand GetPosterCommand { get; set; }
        [Inject]
        public IParsePostCommand ParsePostCommand { get; set; }
        [Inject]
        public ISavePostCommand SavePostCommand { get; set; }
        [Inject]
        public ISavePosterCommand SavePosterCommand { get; set; }
        [Inject]
        public ISaveIssueCommand SaveIssueCommand { get; set; }

        [Inject]
        public ISaveLinkCommand SaveLinkCommand { get; set; }

        [Inject]
        public IIssueRepository IssueRepository { get; set; } 

        [Inject]
        public INetworkHelper NetworkHelper { get; set; }

        public Post GetFromUrl(string permalink)
        {
            Post post = GetPostCommand.Execute(permalink);
            if (post != null)
                return post;
            Blog blog = GetBlogCommand.Execute(permalink);
            if (blog == null) return null;
            PostValues values = ParsePostCommand.Execute(permalink);
            List<Alias> aliases = null;
            List<Url> urls = null;
            if (values.HasAliases)
                aliases = CreateAliasesCommand.Execute(blog.BlogKeyType, values.Aliases);

            if (values.HasLinks)
            {
                IDictionary<string, Domain> domainsDict = CreateDomainsCommand.Execute(values.Links);
                urls = CreateUrlsCommand.Execute(domainsDict);
            }

            post = CreatePostCommand.Execute(values, aliases, urls);
            return post;
        }
        public PostValues GetPostValues(string permalink)
        {
            return ParsePostCommand.Execute(permalink);
        }

        public Post GetFromPostValues(PostValues values)
        {
            return CreatePostCommand.Execute(values, null, null);
        }

        public bool Save(Post post)
        {
            Post entity = GetPostCommand.Execute(post.Permalink);
            return SavePostCommand.Execute(entity, post);
        }

        public Poster AddPoster(int postID, string aliasName)
        {
            Poster poster = GetPosterCommand.Execute(postID, aliasName);
            if (poster == null)
            {
                Post post = GetPostCommand.Execute(postID);
                Alias alias = CreateAliasesCommand.Execute(post.BlogKeyType, aliasName);
                poster = SavePosterCommand.Execute(postID, alias);
                post.Posters.Add(poster);
                SavePostCommand.Execute(post);
            }
            return poster;
        }

        public Link AddLink(int postID, string linkUrl)
        {
            return AddLink(postID, linkUrl, ToneType.Neutral);
        }

        public Link AddLink(int postID, string linkUrl, ToneType toneType)
        {
            Link link = GetLinkCommand.Execute(postID, linkUrl);
            if (link == null)
            {
                IDictionary<string, Domain> dict = CreateDomainsCommand.Execute(new string[] { linkUrl });
                Url url = CreateUrlsCommand.Execute(dict).FirstOrDefault();
                link = SaveLinkCommand.Execute(postID, url, toneType);
            }
            return link;
        }

        public Issue AddIssue(int postID, string topicName)
        {
            return AddIssue(postID, topicName, AffectiveFrameType.Neutral);
        }

        public Issue AddIssue(int postID, string topicName, AffectiveFrameType affectiveFrameType)
        {
            return SaveIssueCommand.Execute(postID, topicName, affectiveFrameType);
        }
    }
}
